#include "checkconstraint.h"

#include "columnReference.h"
#include "logicUnaryOperation.h"
#include "logicBinaryOperation.h"
#include "numericBinaryOperation.h"
#include "numericUnaryOperation.h"

#include <stack>

#include "columnlist.h"

CheckConstraint::CheckConstraint(BooleanExpression * expr,string tableName)
{
  if(tableName!="")setTableName(tableName);//set the table name for column references without it

    //
    if(expr == NULL) this->expr = NULL;
    else this->expr = dynamic_cast<BooleanExpression*> (expr->clone());
}

CheckConstraint::~CheckConstraint()
{
  delete expr; expr = NULL; // NULL
}

CheckConstraint::CheckConstraint(const CheckConstraint& other)
{
  if(other.expr != NULL) expr =  dynamic_cast<BooleanExpression*> (other.expr->clone());
  else expr = NULL;
}

string CheckConstraint::toString()
{
  string str = "[PRIMARY KEY: ";
  if(expr != NULL){
    str = str + expr->toString();
  } //if
  return str + "]";
}

TableConstraint * CheckConstraint::clone()
{
  return new CheckConstraint(* this);
}

void CheckConstraint::setTableName(string tableName){
  Expression * result = expr->clone();
  Expression * pointer = result;

  /* 
     ColumnReference * cr = dynamic_cast<ColumnReference *>(pointer);
     if(cr != NULL){
     Expression * substitution = NULL;
     if(cr->getTableId() == ""){
     string table_name = searchForTable(cr->getColumnId(),from_components,upper_from_components);
     substitution = searchSubstitution(table_name+"."+cr->getColumnId(),substitutions,upper_substitutions);
     }else substitution = searchSubstitution(cr->getTableId()+"."+cr->getColumnId(),substitutions,upper_substitutions);
     delete result; result = NULL;
     result = substitution->clone();
     return result;
     }//if
  */
  stack<Expression *> lifo;
  lifo.push(pointer);
  while(!lifo.empty()){
    pointer = lifo.top();
    lifo.pop();
    LogicBinaryOperation * lbe = dynamic_cast<LogicBinaryOperation *>(pointer);
    if(lbe != NULL){
      ColumnReference * crr = dynamic_cast<ColumnReference *>(lbe->getRightExpression());
      if(crr != NULL){
	Expression * substitution = NULL;
	if(crr->getTableId() == "") crr->setTableId(tableName);
      }
      else{
	lifo.push(lbe->getRightExpression());
      }// if-else

      ColumnReference * crl = dynamic_cast<ColumnReference *>(lbe->getLeftExpression());
      if(crl != NULL){
	Expression * substitution = NULL;
	if(crl->getTableId() == "") crl->setTableId(tableName);
	}
      else{
	lifo.push(lbe->getLeftExpression());
      }// if-else
      }else{
	LogicUnaryOperation * lue = dynamic_cast<LogicUnaryOperation *>(pointer);
	if(lue != NULL){
	  ColumnReference * cr = dynamic_cast<ColumnReference *>(lue->getExpression());
	  if(cr != NULL){
	    Expression * substitution = NULL;
	    if(cr->getTableId() == "")cr->setTableId(tableName);
	  }else{
	    lifo.push(lue->getExpression());
	  }// if-else
	}else{
	  NumericBinaryOperation * nbe = dynamic_cast<NumericBinaryOperation *>(pointer);
	  if(nbe != NULL){
	    ColumnReference * crr = dynamic_cast<ColumnReference *>(nbe->getRightExpression());
	    if(crr != NULL){
	      Expression * substitution = NULL;
	      if(crr->getTableId() == "")crr->setTableId(tableName);
		}else{
	      lifo.push(nbe->getRightExpression());
	    }// if-else

	    ColumnReference * crl = dynamic_cast<ColumnReference *>(nbe->getLeftExpression());
	    if(crl != NULL){
	      Expression * substitution = NULL;
	      if(crl->getTableId() == "")crl->setTableId(tableName);
	    }else{
	      lifo.push(nbe->getLeftExpression());
	    }// if-else
	  }else{
	    NumericUnaryOperation * nue = dynamic_cast<NumericUnaryOperation *>(pointer);
	    if(nue != NULL){
	      ColumnReference * cr = dynamic_cast<ColumnReference *>(nue->getExpression());
	      if(cr != NULL){
		Expression * substitution = NULL;
		if(cr->getTableId() == "")cr->setTableId(tableName);
	      }else{
		lifo.push(nue->getExpression());
	      }// if-else
	    }else{
	      // NOTHING TO DO
	    }// if-else
	  }// if-else
	}// if-else
      }//if-else
    }// while*/
  this->expr = dynamic_cast<BooleanExpression*>(result);
}
